package com.cyy.service.Impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.cyy.common.Coin;
import com.cyy.common.CoinConfig;
import com.cyy.common.CommonException;
import com.cyy.service.ConfigService;
import com.cyy.service.HttpService;
import com.cyy.service.RpcService;
import com.cyy.util.Utils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.BigInteger;

@Service("sipeRpcServiceImpl")
public class SipeRpcServiceImpl implements RpcService {

    private Logger logger = LoggerFactory.getLogger(SipeRpcServiceImpl.class);

    @Autowired
    private ConfigService configService;

    @Autowired
    private HttpService httpService;

    @Override
    public String getName(){
        return Coin.SIPE;
    }

    private JSONObject getParams(String method,Object... params){
        JSONObject param = new JSONObject();
        param.put("jsonrpc","2.0");
        param.put("method",method);
        JSONArray array = new JSONArray();
        if(params != null && params.length > 0){
            for(Object item : params) {
                array.add(item);
            }
        }
        param.put("params",array);
        param.put("id",1);
        return param;
    }

    /**
     * 更具交易返回的 hash 查询交易信息
     * @param hexString
     * @return
     */
    @Override
    public JSONObject getTransactionByHash(String hexString){
        logger.info("hexString={}",hexString+"$$$$$");
        CoinConfig config = configService.get(this.getName());
        JSONObject params = this.getParams("eth_getTransactionByHash",hexString);
        logger.info("params:{}",params.toJSONString());
        String res = httpService.post(config.getUrl(),params.toJSONString());
        logger.info("res="+res);
        if(StringUtils.isBlank(res)){
            return null;
        }
        JSONObject json = JSONObject.parseObject(res);
        JSONObject error = json.getJSONObject("error");
        if(error != null){
            throw new CommonException(error.getString("code"),error.getString("message"));
        }
        return json.getJSONObject("result");
    }


    /**
     * 地址获取
     * @return
     */
    @Override
    public JSONArray getAccount(){
        CoinConfig config = configService.get(this.getName());
        JSONObject params = this.getParams("eth_accounts",null);
        String res = httpService.post(config.getUrl(),params.toJSONString());
        logger.info("res="+res);
        if(StringUtils.isBlank(res)){
            return null;
        }
        JSONObject json = JSONObject.parseObject(res);
        JSONObject error = json.getJSONObject("error");
        if(error != null){
            throw new CommonException(error.getString("code"),error.getString("message"));
        }
        return json.getJSONArray("result");
    }

    /**
     * 返回账户余额
     */
    public String getBalance(String address){
        CoinConfig config = configService.get(this.getName());
        JSONObject params = this.getParams("eth_getBalance",address,"latest");
        String res = httpService.post(config.getUrl(),params.toJSONString());

        JSONObject json = JSONObject.parseObject(res);
        JSONObject error = json.getJSONObject("error");
        if(error != null){
            throw new CommonException(error.getString("code"),error.getString("message"));
        }
        String txt = json.getString("result");
        logger.info("getBalance:=" + txt+",sub:"+txt.substring(2));
        return  new BigInteger(txt.substring(2),16).toString();
        // return json.getJSONArray("result");
    }


    public String sendTransaction(String toAddr,String payAddr,String price,String minerFee){

        CoinConfig config = configService.get(this.getName());

        minerFee = StringUtils.isBlank(minerFee)?"0":minerFee;

        JSONObject value = new JSONObject();
        value.put("from",payAddr);
        value.put("to",toAddr);

        BigInteger fee = (new BigDecimal(minerFee).multiply(new BigDecimal(config.getUnit()))).toBigInteger();

        BigInteger _price = (new BigDecimal(price).multiply(new BigDecimal(config.getUnit()))).toBigInteger();
        BigInteger _val = _price.subtract(fee);
        if(_val.compareTo(BigInteger.ZERO) <= 0){
            throw new CommonException("费用高于转账总金额");
        }
        value.put("value","0x"+_val.toString(16));
        value.put("data", Utils.strTo16("转账"));

        JSONObject params = this.getParams("eth_sendTransaction",value);
        String res = httpService.post(config.getUrl(),params.toJSONString());

        JSONObject json = JSONObject.parseObject(res);
        JSONObject error = json.getJSONObject("error");
        if(error != null){
            throw new CommonException(error.getString("code"),error.getString("message"));
        }
        return json.getString("result");

    }
}
